extern crate pest;
extern crate rustyline;

#[macro_use]
extern crate pest_derive;

use pest::Parser;
use pest::iterators::Pair;
use pest::iterators::Pairs;
// use std::fs;
// use std::path::Path;

use rustyline::error::ReadlineError;
use rustyline::Editor;


// Tell Rust, that the struct below shall be created from the grammar
// in the referenced file.
#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct PolishNotationParser;


const HISTORY_FILENAME: &str = "history.txt";
const PROMPT: &str = "LISPY>> ";


fn print_initial_info() {
    println!("Lispy Version 0.0.1");
    println!("Press Ctrl+c to Exit.\n");
}


fn eval(lispy: Pairs<Rule>) {
    for pair in lispy {
        // match pair.as_rule() {
        //     Rule::phrase => {
        //         println!("found a doge phrase while parsing");
        //         doge_phrase_count += 1;
        //     },
        //     Rule::phrase_delimiter => (),
        //     Rule::EOI => println!("found EOI while parsing"),
        //     _ => {
        //         println!("found {}:", pair);
        //         unreachable!();
        //     }
        // }
        println!("{}", pair);
    }
}

fn repl(mut readline_editor: Editor<()>) {
    loop {
        let readline = readline_editor.readline(PROMPT);
        match readline {
            Ok(line) => {
                readline_editor.add_history_entry(line.as_ref());
                match PolishNotationParser::parse(Rule::lispy, &line) {
                    Ok(parsing_result) => {
                        println!("Parsing OK: {}", parsing_result);
                        eval(parsing_result);
                    },
                    Err(some_err) => {
                        println!("There was an error while parsing: {:?}", some_err);
                    }
                }
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
        readline_editor
            .save_history(HISTORY_FILENAME)
            .expect("Could not save to readline history.");
    }
}


fn main() {
    // We create an editor for the readline history.
    let mut readline_editor = Editor::<()>::new();
    // And then load the history, if it exists.
    if readline_editor.load_history(HISTORY_FILENAME).is_err() {
        println!("No previous history.");
    }
    print_initial_info();
    repl(readline_editor);
}
